{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# AutoEncoder\n",
    "- 大致是一个将数据的高维特征进行压缩降维编码，再经过相反的解码过程的一种学习方法。学习过程中通过解码得到的最终结果与原数据进行比较，通过修正权重偏置参数降低损失函数，不断提高对原数据的复原能力。\n",
    "- 学习完成后，前半段的编码过程得到结果即可代表原数据的低维“特征值”。通过学习得到的自编码器模型可以实现将高维数据压缩至所期望的维度，原理与PCA相似"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from tensorflow.examples.tutorials.mnist import input_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./mnist_data_sets/train-images-idx3-ubyte.gz\n",
      "Extracting ./mnist_data_sets/train-labels-idx1-ubyte.gz\n",
      "Extracting ./mnist_data_sets/t10k-images-idx3-ubyte.gz\n",
      "Extracting ./mnist_data_sets/t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "mnist = input_data.read_data_sets(\"./mnist_data_sets/\", one_hot=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "learining_rate = 0.01\n",
    "trainging_epochs = 10\n",
    "batch_size = 256\n",
    "display_step = 1\n",
    "example_to_show = 10\n",
    "n_input = 784\n",
    "n_out = 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "X = tf.placeholder(\"float\", [None, n_input])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "n_hidden_1 = 256\n",
    "n_hidden_2 = 128"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "weights = {\n",
    "    \"encoder_h1\": tf.Variable(tf.random_normal([n_input, n_hidden_1])),\n",
    "    \"encoder_h2\": tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),\n",
    "    \"decoder_h1\": tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),\n",
    "    \"decoder_h2\": tf.Variable(tf.random_normal([n_hidden_1, n_input])),\n",
    "    \"out\": tf.Variable(tf.random_normal([n_hidden_2, n_out])),\n",
    "}\n",
    "biases = {\n",
    "    \"encoder_b1\": tf.Variable(tf.random_normal([n_hidden_1])),\n",
    "    \"encoder_b2\": tf.Variable(tf.random_normal([n_hidden_2])),\n",
    "    \"decoder_b1\": tf.Variable(tf.random_normal([n_hidden_1])),\n",
    "    \"decoder_b2\": tf.Variable(tf.random_normal([n_input])),\n",
    "    \"out\":  tf.Variable(tf.random_normal([n_out])),\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 激励函数使用sigmoid, 使用relu之后，cost增大，效果不好，pred的图像不能显示"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def Encoder(X):\n",
    "    layer_1 = tf.nn.sigmoid(tf.matmul(X, weights[\"encoder_h1\"]) + biases[\"encoder_b1\"])\n",
    "    layer_2 = tf.nn.sigmoid(tf.matmul(layer_1, weights[\"encoder_h2\"]) + biases[\"encoder_b2\"])\n",
    "    return layer_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def Encoder_classifier(X):\n",
    "    layer_1 = tf.nn.sigmoid(tf.matmul(X, weights[\"encoder_h1\"]) + biases[\"encoder_b1\"])\n",
    "    layer_2 = tf.nn.sigmoid(tf.matmul(layer_1, weights[\"encoder_h2\"]) + biases[\"encoder_b2\"])\n",
    "    layer_out = tf.nn.softmax(tf.matmul(layer_2, weights[\"out\"]) + biases[\"out\"])\n",
    "    return layer_out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def Decoder(X):\n",
    "    layer_1 = tf.nn.sigmoid(tf.matmul(X, weights[\"decoder_h1\"]) + biases[\"decoder_b1\"])\n",
    "    layer_2 = tf.nn.sigmoid(tf.matmul(layer_1, weights[\"decoder_h2\"]) + biases[\"decoder_b2\"])\n",
    "    return layer_2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "encoder_op = Encoder(X)\n",
    "decoder_op = Decoder(encoder_op)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "y_pred = decoder_op\n",
    "y_true = X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "cost = tf.reduce_mean(tf.pow(y_pred - y_true, 2))\n",
    "optimizer = tf.train.AdamOptimizer(learining_rate).minimize(cost)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "``` python\n",
    "with tf.Session() as sess:  \n",
    "    # tf.initialize_all_variables() no long valid from  \n",
    "    # 2017-03-02 if using tensorflow >= 0.12  \n",
    "    if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:  \n",
    "        init = tf.initialize_all_variables()  \n",
    "    else:  \n",
    "        init = tf.global_variables_initializer()  \n",
    "    sess.run(init) \n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Epoch: ', '0001', 'cost = ', '0.087389670')\n",
      "('Epoch: ', '0002', 'cost = ', '0.075218834')\n",
      "('Epoch: ', '0003', 'cost = ', '0.073462784')\n",
      "('Epoch: ', '0004', 'cost = ', '0.069760896')\n",
      "('Epoch: ', '0005', 'cost = ', '0.063400418')\n",
      "('Epoch: ', '0006', 'cost = ', '0.064577252')\n",
      "('Epoch: ', '0007', 'cost = ', '0.060670465')\n",
      "('Epoch: ', '0008', 'cost = ', '0.060586091')\n",
      "('Epoch: ', '0009', 'cost = ', '0.058880661')\n",
      "('Epoch: ', '0010', 'cost = ', '0.058895446')\n",
      "Optimization Finished\n"
     ]
    },
    {
     "data": {
      "image/png": "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\ngiOcWICNHePVJQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f65dacab690>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "init = tf.global_variables_initializer()\n",
    "with tf.Session() as sess:\n",
    "    sess.run(init)\n",
    "    # 首先计算总批数，保证每次循环 epoch 训练集中的每个样本都参与训练，不同于批量训练\n",
    "    total_patch = int(mnist.train.num_examples / batch_size)\n",
    "    for epoch in range(trainging_epochs):\n",
    "        for i in range(total_patch):\n",
    "            batch_xs, batch_ys = mnist.train.next_batch(batch_size)\n",
    "            _, c = sess.run([optimizer, cost], feed_dict = {X: batch_xs})\n",
    "        if (epoch % display_step) == 0:\n",
    "            print(\"Epoch: \", \"%04d\" % (epoch + 1), \"cost = \", \"{:.9f}\".format(c))\n",
    "    print(\"Optimization Finished\")\n",
    "    \n",
    "    encoder_decoder = sess.run(y_pred, feed_dict={X: mnist.test.images[:example_to_show]})\n",
    "    f, a = plt.subplots(2, 10, figsize = (10, 2))\n",
    "    for i in range(example_to_show):\n",
    "        a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))\n",
    "        a[1][i].imshow(np.reshape(encoder_decoder[i], (28, 28)))\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
